﻿namespace Atomic.Mvc.ViewEngines
{
    using System;
    using System.Web.Mvc;

    using Atomic.Caching;

    using Atomic.Mvc.Settings;
    using Atomic.Mvc.Properties;

    /// <summary>
    /// Rzaor 视图引擎提供程序。
    /// </summary>
    public class DefaultRzaorViewEngineProvider : IRzaorViewEngineProvider
    {
        /// <summary>
        /// 布局管理器。
        /// </summary>
        private readonly ILayoutManager _layoutManager = null;

        /// <summary>
        /// 初始化 Rzaor 视图引擎提供程序。
        /// </summary>
        /// <param name="layoutManager">布局管理器。</param>
        public DefaultRzaorViewEngineProvider(ILayoutManager layoutManager)
        {
            this._layoutManager = layoutManager;
        }

        /// <summary>
        /// 创建视图引擎。
        /// </summary>
        /// <param name="controllerContext">控制器上下文。</param>
        /// <returns>视图引擎。</returns>
        public IViewEngine CreateViewEngine(ControllerContext controllerContext)
        {
            string pluginName = string.Empty;

            if (controllerContext.RouteData.Values.ContainsKey(Resources.VIEW_PLUGIN_NAME))
            {
                pluginName = controllerContext.RouteData.GetRequiredString(Resources.VIEW_PLUGIN_NAME);
            }

            return this.CreateViewEngine(pluginName);
            //return CacheManager.Current.GetOrAdd(Resources.VIEW_ENGINE_CACHE_NAME + pluginName, () => this.CreateViewEngine(pluginName));
        }

        /// <summary>
        /// 创建视图引擎。
        /// </summary>
        /// <remarks>
        /// 根据插件名称创建带有不同搜索路径的视图引擎。
        /// </remarks>
        /// <param name="pluginName">插件名称。</param>
        /// <returns>视图引擎。</returns>
        private IViewEngine CreateViewEngine(string pluginName)
        {
            var site = SiteFactory.Current;

            if (site.Theme.Equals("Default", StringComparison.OrdinalIgnoreCase))
            {
                return this.CreateDefaultEngine(pluginName);
            }

            return this.CreateThemeEngine(site.Theme, pluginName);
        }

        /// <summary>
        /// 创建默认的视图引擎。
        /// </summary>
        /// <param name="pluginName">插件名称。</param>
        /// <returns>视图引擎。</returns>
        private IViewEngine CreateDefaultEngine(string pluginName)
        {
            var areaFormats = new[] 
            {
                "~/Core/{2}/Themes/Default/Views/{1}/{0}.cshtml",
                "~/Core/{2}/Themes/Default/Views/Shared/{0}.cshtml",
                "~/Core/{2}/Views/{1}/{0}.cshtml",
                "~/Core/{2}/Views/Shared/{0}.cshtml",
                "~/Plugins/{2}/Themes/Default/Views/{1}/{0}.cshtml",
                "~/Plugins/{2}/Themes/Default/Views/Shared/{0}.cshtml",
                "~/Plugins/{2}/Views/{1}/{0}.cshtml",
                "~/Plugins/{2}/Views/Shared/{0}.cshtml",
                "~/Themes/Default/Views/{1}/{0}.cshtml",
                "~/Themes/Default/Views/Shared/{0}.cshtml",
                "~/Views/{1}/{0}.cshtml",
                "~/Views/Shared/{0}.cshtml",
            };

            var viewFormats = new[] 
            {
                "~/Themes/Default/Views/{1}/{0}.cshtml",
                "~/Themes/Default/Views/Shared/{0}.cshtml",
            };

            if (!string.IsNullOrWhiteSpace(pluginName))
            {
                viewFormats = new[] 
                {
                    "~/Core/" + pluginName + "/Themes/Default/Views/{1}/{0}.cshtml",
                    "~/Core/" + pluginName + "/Themes/Default/Views/Shared/{0}.cshtml",
                    "~/Core/" + pluginName + "/Views/{1}/{0}.cshtml",
                    "~/Core/" + pluginName + "/Views/Shared/{0}.cshtml",
                    "~/Plugins/" + pluginName + "/Themes/Default/Views/{1}/{0}.cshtml",
                    "~/Plugins/" + pluginName + "/Themes/Default/Views/Shared/{0}.cshtml",
                    "~/Plugins/" + pluginName + "/Views/{1}/{0}.cshtml",
                    "~/Plugins/" + pluginName + "/Views/Shared/{0}.cshtml",
                    "~/Themes/Default/Views/{1}/{0}.cshtml",
                    "~/Themes/Default/Views/Shared/{0}.cshtml",
                    "~/Views/{1}/{0}.cshtml",
                    "~/Views/Shared/{0}.cshtml",
                };
            }

            var viewEngine = new AtomicRzaorEngine(this._layoutManager)
            {
                MasterLocationFormats = viewFormats,
                ViewLocationFormats = viewFormats,
                PartialViewLocationFormats = viewFormats,
                AreaMasterLocationFormats = areaFormats,
                AreaViewLocationFormats = areaFormats,
                AreaPartialViewLocationFormats = areaFormats,
            };

            return viewEngine;
        }

        /// <summary>
        /// 创建包含自定义主题的视图引擎。
        /// </summary>
        /// <param name="themeName">主题名称。</param>
        /// <param name="pluginName">插件名称。</param>
        /// <returns>视图引擎。</returns>
        private IViewEngine CreateThemeEngine(string themeName, string pluginName)
        {
            var areaFormats = new[] 
            {
                "~/Core/{2}/Themes/" + themeName + "/Views/{1}/{0}.cshtml",
                "~/Core/{2}/Themes/" + themeName + "/Views/Shared/{0}.cshtml",
                "~/Core/{2}/Themes/Default/Views/{1}/{0}.cshtml",
                "~/Core/{2}/Themes/Default/Views/Shared/{0}.cshtml",
                "~/Core/{2}/Views/{1}/{0}.cshtml",
                "~/Core/{2}/Views/Shared/{0}.cshtml",
                "~/Plugins/{2}/Themes/" + themeName + "/Views/{1}/{0}.cshtml",
                "~/Plugins/{2}/Themes/" + themeName + "/Views/Shared/{0}.cshtml",
                "~/Plugins/{2}/Themes/Default/Views/{1}/{0}.cshtml",
                "~/Plugins/{2}/Themes/Default/Views/Shared/{0}.cshtml",
                "~/Plugins/{2}/Views/{1}/{0}.cshtml",
                "~/Plugins/{2}/Views/Shared/{0}.cshtml",
                "~/Themes/" + themeName + "/Views/{1}/{0}.cshtml",
                "~/Themes/" + themeName + "/Views/Shared/{0}.cshtml",
                "~/Themes/Default/Views/{1}/{0}.cshtml",
                "~/Themes/Default/Views/Shared/{0}.cshtml",
                "~/Views/{1}/{0}.cshtml",
                "~/Views/Shared/{0}.cshtml",
            };

            var viewFormats = new[] 
            {
                "~/Themes/" + themeName + "/Views/{1}/{0}.cshtml",
                "~/Themes/" + themeName + "/Views/Shared/{0}.cshtml",
                "~/Themes/Default/Views/{1}/{0}.cshtml",
                "~/Themes/Default/Views/Shared/{0}.cshtml",
            };

            if (!string.IsNullOrWhiteSpace(pluginName))
            {
                viewFormats = new[] 
                {
                    "~/Core/" + pluginName + "/Themes/" + themeName + "/Views/{1}/{0}.cshtml",
                    "~/Core/" + pluginName + "/Themes/" + themeName + "/Views/Shared/{0}.cshtml",
                    "~/Core/" + pluginName + "/Themes/Default/Views/{1}/{0}.cshtml",
                    "~/Core/" + pluginName + "/Themes/Default/Views/Shared/{0}.cshtml",
                    "~/Core/" + pluginName + "/Views/{1}/{0}.cshtml",
                    "~/Core/" + pluginName + "/Views/Shared/{0}.cshtml",
                    "~/Plugins/" + pluginName + "/Themes/" + themeName + "/Views/{1}/{0}.cshtml",
                    "~/Plugins/" + pluginName + "/Themes/" + themeName + "/Views/Shared/{0}.cshtml",
                    "~/Plugins/" + pluginName + "/Themes/Default/Views/{1}/{0}.cshtml",
                    "~/Plugins/" + pluginName + "/Themes/Default/Views/Shared/{0}.cshtml",
                    "~/Plugins/" + pluginName + "/Views/{1}/{0}.cshtml",
                    "~/Plugins/" + pluginName + "/Views/Shared/{0}.cshtml",
                    "~/Themes/" + themeName + "/Views/{1}/{0}.cshtml",
                    "~/Themes/" + themeName + "/Views/Shared/{0}.cshtml",
                    "~/Themes/Default/Views/{1}/{0}.cshtml",
                    "~/Themes/Default/Views/Shared/{0}.cshtml",
                    "~/Views/{1}/{0}.cshtml",
                    "~/Views/Shared/{0}.cshtml",
                };
            }

            var viewEngine = new AtomicRzaorEngine(this._layoutManager)
            {
                MasterLocationFormats = viewFormats,
                ViewLocationFormats = viewFormats,
                PartialViewLocationFormats = viewFormats,
                AreaMasterLocationFormats = areaFormats,
                AreaViewLocationFormats = areaFormats,
                AreaPartialViewLocationFormats = areaFormats,
            };

            return viewEngine;
        }
    }
}